package cn.com.pc.content.service;


import cn.com.pc.content.domain.Biz;
import cn.com.pc.content.domain.Site;
import cn.com.pc.content.domain.tag.Tag;
import cn.com.pc.content.domain.tag.TagGroup;
import cn.com.pc.content.domain.tag.TagGroupRepository;
import cn.com.pc.content.dto.PageForm;
import cn.com.pc.content.dto.PageResult;
import cn.com.pc.content.dto.Sort;
import cn.com.pc.content.dto.TagGroupDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TagGroupService {

    @Autowired
    private TagGroupRepository tagGroupRepository;

    @Autowired
    private TagService tagService;

    /**
     * 新增标签组
     * @param tagGroupDTO
     * @return
     */
    public Long createTagGroup(TagGroupDTO tagGroupDTO) {
        TagGroup tagGroup = new TagGroup();
        BeanUtils.copyProperties(tagGroupDTO, tagGroup);
        tagGroup = tagGroupRepository.save(tagGroup);
        return tagGroup.getId();
    }

    public boolean existsTagGroupByName(Site site, Biz biz, String name) {
        return tagGroupRepository.existsBySiteAndBizAndName(site, biz, name);
    }


    /**
     * 查询标签组列表
     * @param tagGroupDTO
     * @param pageForm
     * @param sort
     * @return
     */
    public PageResult<TagGroup> listTagGroupsByDTO(TagGroupDTO tagGroupDTO, PageForm pageForm, Sort sort) {
        //查询对象
        TagGroup tagGroup = new TagGroup();
        tagGroup.setSite(tagGroupDTO.getSite());

        if (tagGroupDTO.getBiz() != null) {
            tagGroup.setBiz(tagGroupDTO.getBiz());
        }
        if (tagGroupDTO.getId() != null) {
            tagGroup.setId(tagGroupDTO.getId());
        }
        if (StringUtils.hasLength(tagGroupDTO.getName())) {
            tagGroup.setName(tagGroupDTO.getName());
        }
        if (StringUtils.hasLength(tagGroupDTO.getDescription())) {
            tagGroup.setDescription(tagGroupDTO.getDescription());
        }
        if (tagGroupDTO.getOnShelve() != null) {
            tagGroup.setOnShelve(tagGroupDTO.getOnShelve());
        }

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatcher::contains)
                .withMatcher("description", ExampleMatcher.GenericPropertyMatcher::contains);

        Example<TagGroup> example = Example.of(tagGroup, matcher);
        Pageable pageable;
        if (!StringUtils.hasLength(sort.getSortBy())) {
            sort.setSortBy("id");
        }
        pageable = PageRequest.of(pageForm.getPageNum() - 1, pageForm.getPageSize(), sort.getDirection(), sort.getSortBy());

        Page<TagGroup> tagGroupPage = tagGroupRepository.findAll(example, pageable);
        return PageResult.fromPage(tagGroupPage);
    }


    public TagGroup getTagGroupById(Long tagGroupId) {
        return tagGroupRepository.findById(tagGroupId).orElse(null);
    }


    /**
     * 修改标签组
     * @param tagGroupDTO
     * @param tagGroup
     * @return
     */
    public TagGroup updateTagGroupByDTO(TagGroupDTO tagGroupDTO, TagGroup tagGroup) {
        BeanUtils.copyProperties(tagGroupDTO, tagGroup, "id", "createdAt");
        return tagGroupRepository.save(tagGroup);
    }


    /**
     * 标签组添加标签
     * @param tagGroup
     * @param tagIds
     * @param site
     */
    @Transactional
    public TagGroup addTagsIntoTagGroup(TagGroup tagGroup, List<Long> tagIds, Site site) {
        Map<String, Object> map = tagService.verifyTagIds(new HashSet<>(tagIds), site, true);
        List<Tag> tags = (ArrayList<Tag>) map.get("tags");
        tags = (List<Tag>) CollectionUtils.union(tagGroup.getTags(), tags);
        tagGroup.setTags(tags);
        return tagGroupRepository.save(tagGroup);
    }


    /**
     * 标签组删除标签
     * @param tagGroup
     * @param tagIds
     * @param site
     */
    @Transactional
    public TagGroup removeTagFromTagGroup(TagGroup tagGroup, List<Long> tagIds, Site site) {
        Map<String, Object> map = tagService.verifyTagIds(new HashSet<>(tagIds), site, true);
        List<Tag> tags = (ArrayList<Tag>) map.get("tags");
        tags = (List<Tag>) CollectionUtils.subtract(tagGroup.getTags(), tags);
        tagGroup.setTags(tags);
        return tagGroupRepository.save(tagGroup);
    }
}
